
#ifndef __ARCHIVECALLBACK_H
#define __ARCHIVECALLBACK_H

#include "../../../Common/MyWindows.h"
#include "../../Archive/IArchive.h"
#include "../../IPassword.h"

#include "../../../Common/Defs.h"
#include "../../../Common/MyString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/IntToString.h"

#include "../../../Windows/FileName.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/PropVariantConv.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileFind.h"
#include "../../Common/FileStreams.h"
#include "../../IVrv_Install.h"
#include "DirItem.h"

//////////////////////////////////////////////////////////////
// Archive Open callback class
class CArchiveOpenCallback:
	public IArchiveOpenCallback,
	public ICryptoGetTextPassword,
	public CMyUnknownImp
{
public:
	MY_UNKNOWN_IMP1(ICryptoGetTextPassword)

	STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
	STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);

	STDMETHOD(CryptoGetTextPassword)(BSTR *password);

	bool		m_PasswordIsDefined;
	UString		m_Password;

	CArchiveOpenCallback() : m_PasswordIsDefined(false) {}
};

//////////////////////////////////////////////////////////////
// Archive Extracting callback class
class CArchiveExtractCallback:
	public IArchiveExtractCallback,
	public ICryptoGetTextPassword,
	public CMyUnknownImp
{
 public:
 	MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
 
 		// IProgress
 	STDMETHOD(SetTotal)(UInt64 size);
 	STDMETHOD(SetCompleted)(const UInt64 *completeValue);
 
 	// IArchiveExtractCallback
 	STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);
 	STDMETHOD(PrepareOperation)(Int32 askExtractMode);
 	STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
 
 	// ICryptoGetTextPassword
 	STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);
 
 private:
 	CMyComPtr<IInArchive> _archiveHandler;
 	FString	_directoryPath;  // Output directory
 	UString _filePath;       // name inside arcvhive
 	FString _diskFilePath;   // full path to file on disk
 	bool _extractMode;
 	struct CProcessedFileInfo
 	{
 		FILETIME MTime;
 		UInt32 Attrib;
 		bool isDir;
 		bool AttribDefined;
 		bool MTimeDefined;
 	} _processedFileInfo;
 
 	COutFileStream *_outFileStreamSpec;
 	CMyComPtr<ISequentialOutStream> _outFileStream;
 
 public:
 	void Init(IInArchive *archiveHandler, const FString &directoryPath);
 
 	UInt64	m_NumErrors;
 	bool	m_PasswordIsDefined;
 	UString m_Password;
	pfnGetExtractPath m_pfn;
	void*	m_param;
 
 	CArchiveExtractCallback() : m_PasswordIsDefined(false) {}
};


//////////////////////////////////////////////////////////////
// Archive Creating callback class
class CArchiveUpdateCallback:
	public IArchiveUpdateCallback2,
	public ICryptoGetTextPassword2,
	public CMyUnknownImp
{
 public:
 	MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
 
 		// IProgress
 	STDMETHOD(SetTotal)(UInt64 size);
 	STDMETHOD(SetCompleted)(const UInt64 *completeValue);
 
 	// IUpdateCallback2
 	STDMETHOD(GetUpdateItemInfo)(UInt32 index,
 		Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
 	STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
 	STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
 	STDMETHOD(SetOperationResult)(Int32 operationResult);
 	STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
 	STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
 
 	STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
public:
	const CObjectVector<CDirItem> *	m_DirItems;
 	CRecordVector<UInt64>			m_VolumesSizes;
 	
 
	UString		m_VolName;
	UString		m_VolExt;
	FString		m_DirPrefix;
 	bool		m_PasswordIsDefined;
 	UString		m_Password;
 	bool		m_AskPassword;
 
 	bool		m_NeedBeClosed;
 
 	FStringVector m_FailedFiles;
 	
	CRecordVector<HRESULT> m_FailedCodes;
 
 	CArchiveUpdateCallback(): m_PasswordIsDefined(false), m_AskPassword(false), m_DirItems(0) {};
 
 	~CArchiveUpdateCallback() { Finilize(); }
 	HRESULT Finilize();
 
 	void Init(const CObjectVector<CDirItem> *dirItems)
 	{
 		m_DirItems = dirItems;
 		m_NeedBeClosed = false;
 		m_FailedFiles.Clear();
 		m_FailedCodes.Clear();
 	}
};

#endif 